<!DOCTYPE HTML>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
promise_test(function() {
  return navigator.mediaDevices.getUserMedia({audio: true})
      .then(function(stream) {
    var capabilities = stream.getAudioTracks()[0].getCapabilities();
    assert_equals(Object.keys(capabilities).length, 9);
    assert_true(capabilities.hasOwnProperty('deviceId'));
    assert_true(capabilities.hasOwnProperty('groupId'));
    assert_true(capabilities.hasOwnProperty('sampleSize'));
    assert_true(capabilities.hasOwnProperty('channelCount'));
    assert_true(capabilities.hasOwnProperty('sampleRate'));
    assert_true(capabilities.hasOwnProperty('latency'));
    verifyAudioProcessingProperties(capabilities, true);
  });
}, 'getCapabilities() support for getUserMedia() audio track.');

promise_test(function() {
  return navigator.mediaDevices.getUserMedia({video: true})
      .then(function(stream) {
    var capabilities = stream.getVideoTracks()[0].getCapabilities();
    assert_greater_than(Object.keys(capabilities).length, 0);
    assert_true(capabilities.hasOwnProperty('deviceId'));
    assert_true(capabilities.hasOwnProperty('groupId'));
    assert_true(capabilities.hasOwnProperty('facingMode'));
    verifyVideoRangeProperties(capabilities);
    assert_true(capabilities.hasOwnProperty('resizeMode'));
    assert_in_array('none', capabilities.resizeMode);
    assert_in_array('crop-and-scale', capabilities.resizeMode);
  });
}, 'getCapabilities() support for getUserMedia() video track.');

test(function() {
  var stream = (new AudioContext()).createMediaStreamDestination().stream;
  var capabilities = stream.getAudioTracks()[0].getCapabilities();
  assert_equals(Object.keys(capabilities).length, 5);
  assert_true(capabilities.hasOwnProperty('deviceId'));
  assert_true(capabilities.hasOwnProperty('sampleSize'));
  verifyAudioProcessingProperties(capabilities, false);
}, 'getCapabilities() support for audio track associated with a MediaStreamAudioDestinationNode.');

test(function() {
  var canvas = document.createElement('canvas');
  var stream = canvas.captureStream();
  var capabilities = stream.getVideoTracks()[0].getCapabilities();
  assert_greater_than(Object.keys(capabilities).length, 0);
  assert_true(capabilities.hasOwnProperty('deviceId'));
  assert_true(capabilities.hasOwnProperty('facingMode'));
  assert_equals(Object.keys(capabilities.facingMode).length, 0);
  verifyVideoRangeProperties(capabilities);
  assert_true(capabilities.hasOwnProperty('resizeMode'));
  assert_in_array('none', capabilities.resizeMode);
  assert_in_array('crop-and-scale', capabilities.resizeMode);
}, 'getCapabilities() support for video track associated with a canvas element.');

test(function() {
  var video = document.createElement('video');
  video.src = "../../external/wpt/media/test-av-384k-44100Hz-1ch-320x240-30fps-10kfr.webm";
  video.play();
  video.oncanplay = function() {
    var stream = video.captureStream();
    var audioCapabilities = stream.getAudioTracks()[0].getCapabilities();
    var videoCapabilities = stream.getVideoTracks()[0].getCapabilities();
    assert_equals(Object.keys(audioCapabilities).length, 5);
    assert_true(audioCapabilities.hasOwnProperty('deviceId'));
    assert_true(audioCapabilities.hasOwnProperty('sampleSize'));
    verifyAudioProcessingProperties(audioCapabilities, false);
    assert_greater_than(Object.keys(videoCapabilities).length, 0);
    assert_true(videoCapabilities.hasOwnProperty('deviceId'));
    assert_true(videoCapabilities.hasOwnProperty('facingMode'));
    assert_equals(Object.keys(videoCapabilities.facingMode).length, 0);
    verifyVideoRangeProperties(videoCapabilities);
    assert_true(videoCapabilities.hasOwnProperty('resizeMode'));
    assert_in_array('none', videoCapabilities.resizeMode);
    assert_in_array('crop-and-scale', videoCapabilities.resizeMode);
  };
}, 'getCapabilities() support for audio and video tracks associated with a video element.');

promise_test(function() {
  var caller = new RTCPeerConnection();
  var callee = new RTCPeerConnection();
  return navigator.mediaDevices.getUserMedia({audio:true, video:true})
  .then((stream) => {
    caller.addStream(stream);
    return createAndSetOffer(caller, callee);
  }).then(() => {
    var remoteStream = callee.getRemoteStreams()[0];
    var audioCapabilities = remoteStream.getAudioTracks()[0].getCapabilities();
    var videoCapabilities = remoteStream.getVideoTracks()[0].getCapabilities();
    assert_equals(Object.keys(audioCapabilities).length, 5);
    assert_true(audioCapabilities.hasOwnProperty('deviceId'));
    assert_true(audioCapabilities.hasOwnProperty('sampleSize'));
    verifyAudioProcessingProperties(audioCapabilities, false);
    assert_greater_than(Object.keys(videoCapabilities).length, 0);
    assert_true(videoCapabilities.hasOwnProperty('deviceId'));
    assert_true(videoCapabilities.hasOwnProperty('facingMode'));
    assert_equals(Object.keys(videoCapabilities.facingMode).length, 0);
    assert_true(videoCapabilities.hasOwnProperty('resizeMode'));
    assert_in_array('none', videoCapabilities.resizeMode);
    assert_in_array('crop-and-scale', videoCapabilities.resizeMode);
  });
}, 'getCapabilities() support for audio and video tracks associated with a RTCPeerConnection.');

function createAndSetOffer(caller, callee) {
  var description = null;
  return caller.createOffer()
  .then(offer => {
    description = offer;
    return caller.setLocalDescription(description);
  }).then(() => {
    return callee.setRemoteDescription(description);
  });
}

function verifyAudioProcessingProperties(capabilities, is_get_user_media) {
  assert_true(capabilities.hasOwnProperty('echoCancellation'));
  assert_equals(Object.keys(capabilities.echoCancellation).length, is_get_user_media ? 2 : 1);
  assert_true(capabilities.hasOwnProperty('autoGainControl'));
  assert_equals(Object.keys(capabilities.autoGainControl).length, is_get_user_media ? 2 : 1);
  assert_true(capabilities.hasOwnProperty('noiseSuppression'));
  assert_equals(Object.keys(capabilities.noiseSuppression).length, is_get_user_media ? 2 : 1);
}

function verifyVideoRangeProperties(capabilities) {
  if (capabilities.hasOwnProperty('width')) {
      assert_equals(Object.keys(capabilities.width).length, 2);
      assert_true(capabilities.width.hasOwnProperty('min'));
      assert_true(capabilities.width.hasOwnProperty('max'));
      assert_less_than_equal(capabilities.width.min, capabilities.width.max);
  }
  if (capabilities.hasOwnProperty('height')) {
    assert_equals(Object.keys(capabilities.height).length, 2);
    assert_true(capabilities.height.hasOwnProperty('min'));
    assert_true(capabilities.height.hasOwnProperty('max'));
    assert_less_than_equal(capabilities.height.min, capabilities.height.max);
  }
  if (capabilities.hasOwnProperty('aspectRatio')) {
    assert_equals(Object.keys(capabilities.aspectRatio).length, 2);
    assert_true(capabilities.aspectRatio.hasOwnProperty('min'));
    assert_true(capabilities.aspectRatio.hasOwnProperty('max'));
    assert_less_than_equal(capabilities.aspectRatio.min, capabilities.aspectRatio.max);
  }
  if (capabilities.hasOwnProperty('frameRate')) {
    assert_equals(Object.keys(capabilities.frameRate).length, 2);
    assert_true(capabilities.frameRate.hasOwnProperty('min'));
    assert_true(capabilities.frameRate.hasOwnProperty('max'));
    assert_less_than_equal(capabilities.frameRate.min, capabilities.frameRate.max);
  }
}
</script>
